package org.bjf.utils;

import com.alibaba.fastjson2.JSON;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author bjf on 2021/4/14.
 * @version 1.022222
 */
public class OkHttp {
    private static Logger log = LoggerFactory.getLogger(OkHttp.class);
    private static OkHttpClient okHttpClient;


    static {

        ConnectionPool pool = new ConnectionPool(50, 5, TimeUnit.MINUTES);

        Interceptor logInterceptor = chain -> {
            Request req = chain.request();
            log.info("http请求信息，url:{},method,{},body:{},header:{}", req.url(), req.method(), req.body(), req.headers());

            Response resp = chain.proceed(req);
            ResponseBody respBody = resp.peekBody(1024 * 1024);
            log.info("http响应信息，code:{},message:{},protocol:{},body:{}", resp.code(), resp.message(), resp.protocol(), respBody.string());
            return resp;
        };

        okHttpClient = new OkHttpClient().newBuilder()
                .retryOnConnectionFailure(false)
                .connectionPool(pool)
                // 连接超时时间
                .connectTimeout(5, TimeUnit.SECONDS)
                //设置新连接的默认读取超时时间
                .readTimeout(10, TimeUnit.SECONDS)
                //设置新连接的默认写入超时
                .writeTimeout(10, TimeUnit.SECONDS)
                // 打印日志拦截器
                .addInterceptor(logInterceptor)
                .build();

    }


    public static HttpObj get(String url) {
        return get(url, null);
    }

    public static HttpObj get(String url, Map<String, Object> params) {
        return getHttpObj(url, params, null);
    }

    public static HttpObj get(String url, Map<String, Object> params, Map<String, String> headers) {
        return getHttpObj(url, params, headers);
    }

    public static HttpObj getHttpObj(String url, Map<String, Object> params,
                                     Map<String, String> headers) {

        //====拼接url参数
        StringBuffer sb = new StringBuffer(url);
        if (params != null && params.size() > 0) {
            sb.append("?");
            params.forEach((k, v) -> sb.append(k).append("=").append(v.toString()));
        }
        //====构造Request
        Request.Builder requestBuilder = new Request.Builder().get().url(sb.toString());
        addHeaders(headers, requestBuilder);
        Request request = requestBuilder.build();
        //====执行Call，得到response
        return execute(request);
    }

    /**
     * 表单提交
     */
    public static HttpObj postForm(String url, Map<String, Object> params) {
        return postForm(url, params, null);
    }

    /**
     * 表单提交
     */
    public static HttpObj postForm(String url, Map<String, Object> params, Map<String, String> headers) {
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (params != null && params.size() > 0) {
            params.forEach((k, v) -> formBuilder.add(k, v.toString()));
        }
        FormBody formBody = formBuilder.build();

        //====构造Request
        Request.Builder requestBuilder = new Request.Builder().post(formBody).url(url);
        addHeaders(headers, requestBuilder);
        Request request = requestBuilder.build();
        //====执行Call，得到response
        return execute(request);
    }

    /**
     * json提交
     */
    public static HttpObj postJson(String url, String json) {
        return postJson(url, json, null);
    }

    /**
     * json提交
     */
    public static HttpObj postJson(String url, String json, Map<String, String> headers) {
        if (StringUtils.isBlank(json)) {
            json = "{}";
        }
        RequestBody requestBody = RequestBody.Companion.create(JSON.toJSONString(json), MediaType.parse("application/json; charset=utf-8"));

        //====构造Request
        Request.Builder requestBuilder = new Request.Builder().post(requestBody).url(url);
        addHeaders(headers, requestBuilder);
        Request request = requestBuilder.build();
        //====执行Call，得到response
        return execute(request);
    }

    /**
     * 添加header信息
     */
    private static Request.Builder addHeaders(Map<String, String> headerMap, Request.Builder builder) {
        if (headerMap != null && !headerMap.isEmpty()) {
            headerMap.forEach((key, value) -> builder.addHeader(key, value));
        }
        return builder;
    }

    private static HttpObj execute(Request request) {
        //====执行Call，得到response
        Call call = okHttpClient.newCall(request);

        try {
            Response response = call.execute();
            return new HttpObj(response.code(), response.body().string());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
